<template>
	<div
		class="d-sm-flex justify-content-lg-end gap-lg-4"
		:class="showMonth ? 'justify-content-between' : 'justify-content-end'"
	>
		<div v-if="showMonth" class="d-none d-sm-flex justify-content-between">
			<DateNavigatorButton
				prev
				:disabled="!hasPrevMonth"
				:onClick="emitPrevMonth"
				data-testid="navigate-prev-month"
			/>
			<CustomSelect
				id="sessionsMonth"
				:options="monthOptions"
				:selected="month"
				@change="emitMonth($event.target.value)"
			>
				<button
					class="btn btn-sm border-0 text-truncate h-100"
					style="width: 8em"
					data-testid="navigate-month"
				>
					{{ monthName }}
				</button>
			</CustomSelect>
			<DateNavigatorButton
				next
				:disabled="!hasNextMonth"
				:onClick="emitNextMonth"
				data-testid="navigate-next-month"
			/>
		</div>
		<div v-if="showMonth" class="d-flex d-sm-none justify-content-between">
			<DateNavigatorButton
				prev
				:disabled="!hasPrevMonth"
				:onClick="emitPrevMonth"
				data-testid="navigate-prev-year-month"
			/>
			<CustomSelect
				id="sessionsMonthYear"
				:options="monthYearOptions"
				:selected="month"
				@change="emitMonthYear($event.target.value)"
			>
				<button
					class="btn btn-sm border-0 h-100 text-truncate"
					data-testid="navigate-month-year"
				>
					{{ monthYearName }}
				</button>
			</CustomSelect>
			<DateNavigatorButton
				next
				:disabled="!hasNextMonth"
				:onClick="emitNextMonth"
				data-testid="navigate-next-year-month"
			/>
		</div>
		<div
			v-if="showYear"
			class="justify-content-between"
			:class="showMonth ? 'd-none d-sm-flex' : 'd-flex'"
		>
			<DateNavigatorButton
				prev
				:disabled="!hasPrevYear"
				:onClick="emitPrevYear"
				data-testid="navigate-prev-year"
			/>
			<CustomSelect
				id="sessionsYear"
				:options="yearOptions"
				:selected="year"
				@change="emitYear($event.target.value)"
			>
				<button
					class="btn btn-sm border-0 h-100"
					style="width: 4em"
					data-testid="navigate-year"
				>
					{{ year }}
				</button>
			</CustomSelect>
			<DateNavigatorButton
				next
				:disabled="!hasNextYear"
				:onClick="emitNextYear"
				data-testid="navigate-next-year"
			/>
		</div>
	</div>
</template>

<script>
import CustomSelect from "../CustomSelect.vue";
import DateNavigatorButton from "./DateNavigatorButton.vue";
import formatter from "../../mixins/formatter";

export default {
	name: "DateNavigator",
	components: {
		CustomSelect,
		DateNavigatorButton,
	},
	mixins: [formatter],
	props: {
		month: Number,
		year: Number,
		startDate: Date,
		showMonth: Boolean,
		showYear: Boolean,
	},
	emits: ["update-date"],
	computed: {
		hasPrevMonth() {
			return (
				this.year > this.startDate.getFullYear() ||
				this.month > this.startDate.getMonth() + 1
			);
		},
		hasNextMonth() {
			const now = new Date();
			return this.year < now.getFullYear() || this.month < now.getMonth() + 1;
		},
		hasPrevYear() {
			return this.year > this.startDate.getFullYear();
		},
		hasNextYear() {
			return this.year < new Date().getFullYear();
		},
		monthOptions() {
			return Array.from({ length: 12 }, (_, i) => i + 1).map((month) => ({
				name: this.fmtMonth(new Date(this.year, month - 1, 1)),
				value: month,
			}));
		},
		monthYearOptions() {
			const first = this.startDate;
			const last = new Date();
			const yearMonths = [];
			for (let year = first.getFullYear(); year <= last.getFullYear(); year++) {
				const startMonth = year === first.getFullYear() ? first.getMonth() + 1 : 1;
				const endMonth = year === last.getFullYear() ? last.getMonth() + 1 : 12;
				for (let month = startMonth; month <= endMonth; month++) {
					yearMonths.push({
						name: this.fmtMonthYear(new Date(year, month - 1, 1)),
						value: `${year}-${month}`,
					});
				}
			}
			return yearMonths;
		},
		yearOptions() {
			const first = this.startDate;
			const last = new Date();
			const years = [];
			for (let year = first.getFullYear(); year <= last.getFullYear(); year++) {
				years.push({ name: year, value: year });
			}
			return years;
		},
		monthName() {
			const date = new Date();
			date.setMonth(this.month - 1, 1);
			return this.fmtMonth(date);
		},
		monthYearName() {
			const date = new Date();
			date.setMonth(this.month - 1, 1);
			date.setFullYear(this.year);
			return this.fmtMonthYear(date);
		},
	},
	methods: {
		emitPrevMonth() {
			const prevMonthDate = new Date(this.year, this.month - 2, 1);
			this.$emit("update-date", {
				year: prevMonthDate.getFullYear(),
				month: prevMonthDate.getMonth() + 1,
			});
		},
		emitNextMonth() {
			const nextMonthDate = new Date(this.year, this.month, 1);
			this.$emit("update-date", {
				year: nextMonthDate.getFullYear(),
				month: nextMonthDate.getMonth() + 1,
			});
		},
		emitPrevYear() {
			this.$emit("update-date", { year: this.year - 1, month: undefined });
		},
		emitNextYear() {
			this.$emit("update-date", { year: this.year + 1, month: undefined });
		},
		emitMonth(month) {
			this.$emit("update-date", { year: this.year, month });
		},
		emitMonthYear(monthYear) {
			const [year, month] = monthYear.split("-");
			this.$emit("update-date", { year: parseInt(year), month: parseInt(month) });
		},
		emitYear(year) {
			this.$emit("update-date", { year, month: undefined });
		},
	},
};
</script>

<style scoped>
.btn {
	color: inherit;
}
</style>
